/**
	Constructs a 

	@author Matthew Richmond
	@version 2006-04-29

	@usage

	- Activate with:
	<code>

	</code>

*/
class timber.ui.LayoutElement {

	private var obj:Object; //clip to control
	private var parentObj:Object;
	//private var parentScale9Grid:Boolean = false;
	
	/* This is tricky, sometimes when a clip is not on the stage you will want it
	to layout based upon the sizing of it's parent. Other times you just want to
	get it off the stage but layout as if it was on the stage*/
	
	private var useStage:Object = true; // layout based upon the stage or the parent clip
	//private var onStage:Boolean = false; // is the object on the stage
	//private var isController:Boolean = false; 
	
	private var horizontalAlign:String; //"left", "right", "center", "auto"
	private var verticalAlign:String; //"top", "bottom", "center", "auto"
	private var horizontalResize:String; //"off", "on", "auto"
	private var verticalResize:String; //"off", "on", "auto"
	
	private var initX:Number;
	private var initY:Number;
	private var initWidth:Number;
	private var initHeight:Number;
		
	private var initTop:Number;
	private var initBottom:Number;
	private var initLeft:Number;
	private var initRight:Number;
	
	private var initTopPad:Number;
	private var initBottomPad:Number;
	private var initLeftPad:Number;
	private var initRightPad:Number;
	
	private var initWidthPercent:Number;
	private var initHeightPercent:Number;
	
	private var initParentWidth:Number;
	private var initParentHeight:Number;
	
	private var minX:Number;
	private var maxX:Number;
	private var minY:Number;
	private var maxY:Number;
	
	private var minWidth:Number;
	private var minHeight:Number;

// ===========================================================
// - CONSTRUCTOR
// ===========================================================

	/**
	Constructor

	@param	obj MovieClip or TextField you wish to position on resize
	@param	hA String ("left", "auto", "right") horozontal alignment
	@param	vA String ("top", "auto", "bottom") vertical alignment 
	@param	hR String ("on", "auto", "off") horozontal resizing
	@param	vR String ("on", "auto", "off") vertical resizing
	@param	uS Optional Boolean (defaults to true) specifying if the layout should be based upon changes in the stage or the parent clip.
	@return	
	*/
	function LayoutElement (obj:Object, hA:String, vA:String, hR:String, vR:String, uS:Boolean) {
		//trace("LayoutElement: "+obj._name);
		
		this.obj = obj;
		
		horizontalAlign = hA;
		verticalAlign = vA;
		horizontalResize = hR;
		verticalResize = vR;
		
		//we assume we will be reacting to changes in stage position
		if (uS == false) {
			this.useStage = false
		}
		
		//update the parent ob
		setParentObj ();

		//trace(obj._name+": useStage="+useStage+", onStage="+onStage);		
		storePositions ();
	};

	/**
	Store al the initial instance vars
	*/
	function storePositions (){
		//trace("LayoutElement: storePositions for "+obj._name);
		
		initX = obj._x;
		initY = obj._y;
		initWidth = calcInitWidth ();
		//trace("initWidth: for "+obj._name+" is: "+initWidth);
		initHeight = calcInitHeight ();
		
		// set the top, bottom, left, right values for clips or text objects
		switch ( typeof(obj) ) {
			case "movieclip" : 
			//trace(obj._name+" switch trace for movieclip");
			
			var bounds_obj:Object = obj.getBounds(obj._parent);
			initTop = bounds_obj.yMin
			initBottom = bounds_obj.yMax
			initLeft = bounds_obj.xMin
			initRight =bounds_obj.xMax
			
			break;
			case "object":
			//trace(obj._name+" switch trace for textobject");
			
			initTop = obj._y
			initBottom = obj._y + obj._height;
			initLeft = obj._x
			initRight = obj._x + obj._width;
			
			break;
		}
	
		//initStageWidth = Stage.width;
		//initStageHeight = Stage.height;
		
		if (useStage != true) {
			//trace("parentObj: "+parentObj);
			initParentWidth = parentObj._width;
			initParentHeight = parentObj._height;
		} else {
			//trace("using stage: setting parentW to "+Stage.width);
			initParentWidth = Stage.width;
			initParentHeight = Stage.height;
		}
		
		
		initTopPad = initTop
		initBottomPad = initParentHeight - initBottom;
		initLeftPad = initLeft
		initRightPad = initParentWidth - initRight;
		
		// get initial percentages for future "auto" scale
		initWidthPercent = calcInitWidthPercent ();
		initHeightPercent = calcInitHeightPercent ();
	};

// ===========================================================
// - ACCESSORS
// ===========================================================


	function setHorozontalRange ( minX:Number, maxX:Number ){
		//trace("LayoutElement: setHorozontalRange");
		
		this.minX = minX;
		this.maxX = maxX;
		
	};

	function setVerticalRange ( minY:Number, maxY:Number){
		//trace("LayoutElement: setVerticalRange");
		
		this.minY = minY;
		this.minX = minX;
		
	};

	function setMinWidth (val:Number){
		//trace("LayoutElement: setMinWidth");
		
		this.minWidth = val
	};

	function setMinHeight (val:Number){
		//trace("LayoutElement: setMinHeight");
		
		this.minHeight = val
	};

// ===========================================================
// - UPDATE
// ===========================================================

	function update (){
		//trace("--- update for "+obj._name);
		
		// update the new positions
		var newParentWidth = calcNewWidth ();
		var newParentHeight = calcNewHeight ();
		
		// change in width is needed for all position types
		/*trace("initParentWidth is: "+initParentWidth);
		trace("newParentWidth is: "+newParentWidth);*/
		
		//trace("was:"+initParentWidth+" | now:"+newParentWidth);
		var deltaW = newParentWidth - initParentWidth;
		var deltaH = newParentHeight - initParentHeight;
		
		// position horizontally
		switch ( horizontalAlign ) {
			case "left" : 
			//trace("switch trace for left");
			
				//calc
				var c:Number = initX; // using initX now
				//if on stage modify 
				if (useStage) c -= (deltaW*.5);
				//set
				updateX(c);

			break;
			case "right":
			//trace("switch trace for right");

				//calc (using initX for position now)
				var c:Number = initParentWidth -initX;
				//if on stage modify 
				if (useStage) c += (deltaW*.5);
				
				//set
				updateX(newParentWidth - c);

			break;
			case "auto":
			//trace("switch trace for auto");

				//calc initial percentage
				var initPercent = initX/initParentWidth * 100				
				//calc
				var c = (newParentWidth/100) * initPercent;
				//if on stage modify 
				if (useStage) c -= (deltaW*.5);
				//set
				updateX(c);
				
			break;
		}

		// position vertically
		switch ( verticalAlign ) {
			case "top" : 
			//trace("switch trace for left");
			
				//calc
				var c:Number = initY; // using initX now
				//if on stage modify 
				if (useStage) c -= (deltaH*.5);
				//set
				updateY(c);

			break;
			case "bottom":
			//trace("switch trace for right");

				//calc (using initX for position now)
				var c:Number = initParentHeight -initY;
				//if on stage modify 
				if (useStage) c += (deltaH*.5);
				
				//set
				updateY(newParentHeight - c);

			break;
			case "auto":
			//trace("switch trace for auto");

				//calc initial percentage
				var initPercent = initY/initParentHeight * 100				
				//calc
				var c = (newParentHeight/100) * initPercent;
				//if on stage modify 
				if (useStage) c -= (deltaH*.5);
				//set
				updateY(c);
				
			break;
		}


		// resize horizontally
		switch ( horizontalResize ) {
			case "on" : 
			//trace("switch trace for on for "+obj._name);
			
				// calc				
				c = newParentWidth - (initLeftPad + initRightPad);
				// set
				updateWidth(c);
				
			break;
			case "auto":
			//trace("switch trace for auto");
				
				//calc
				var c = (newParentWidth/100) * initWidthPercent;
				//set
				updateWidth(c);
				
			break;
		}
		
		// resize vertically
		switch ( verticalResize ) {
			case "on" : 
			//trace("switch trace for on for "+obj._name);
			
				// calc				
				c = newParentHeight - (initTopPad + initBottomPad);
				// set
				updateHeight(c);
				
			break;
			case "auto":
			//trace("switch trace for auto");
				
				//calc
				var c = (newParentHeight/100) * initHeightPercent;
				//set
				updateHeight(c);
				
			break;
		}
		
	};

	// ===========================================================
	// - ACCESSORS
	// ===========================================================	
	
	function setParentObj ():Void{
		//trace("setParentObj");
		if (useStage) {
			parentObj = obj._parent;
		} else {
			parentObj = obj._parent.bg_mc;
		}
		
	};

	// ===========================================================
	// - CALC
	// ===========================================================

	function calcInitWidth ():Number{
		//trace("calcInitWidth: for "+obj._name+" is: "+obj._width);
		return obj._width;
	};

	function calcInitHeight ():Number{
		//trace("calcInitHeight");
		return obj._height;
	};

	function calcInitWidthPercent ():Number{
		//trace("calcInitWidthPercent");
		return initWidth/initParentWidth * 100;
	};
	
	function calcInitHeightPercent ():Number{
		//trace("calcInitHeightPercent");
		return initHeight/initParentHeight * 100;
	};

	function calcNewWidth ():Number{
		//trace("calcNewWidth");
		
		// update the new positions
		if (useStage) {
			var n:Number = Stage.width;
			// if we are limiting width
			if (minWidth) {
				if (n < minWidth) n = minWidth;
			}
		} else {
			var n:Number = parentObj._width;
		}
		
		return n;
	};

	function calcNewHeight ():Number{
		//trace("calcNewHeight");
		
		// update the new positions
		if (useStage) {
			var n:Number = Stage.height;
			// if we are limiting width
			if (minHeight) {
				if (n < minHeight) n = minHeight;
			}
		} else {
			var n:Number = parentObj._height;
		}
		
		return n;
	};

	// ===========================================================
	// - POSITION
	// ===========================================================

	function updateX (v:Number){
		//trace("updateX to "+v);
		obj._x = v;
	};
	
	function updateY (v:Number){
		//trace("updateY");
		obj._y = v;
	};

	function updateWidth (v:Number){
		//trace(obj._name+" updateWidth to "+v);
		obj._width = v;
	};
	
	function updateHeight (v:Number){
		//trace("updateHeight");
		obj._height = v;
	};

};